// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <cstdio>
#include <map>
#include <memory>
#include <string>

#include <rapidjson/document.h>

#include "coin2/exchange/base/order/order.h"

namespace coin2::exchange::okex_v5::order_v5 {

class OkexV5Parser : public base::order::BaseParser {
 public:
  using TransferType = coin::proto::TransferRequestProto::TransferType;

 public:
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& doc) override;
  bool ParseRawBalance(const JsonValue& doc, RawBalanceMap* raw_balance_map);

 private:
  void ParseSubmitResponse();
  void ParseBatchSubmitResponse();
  void ParseCancelResponse();
  void ParseBatchCancelResponse();
  void ParseRestOpenOrders();
  void ParseRestHistOrders();
  void ParseRestFillOrders();
  void ParseRestAccountBalance();
  void ParseWsMessage();

  void ParseWsOrderInfoList(const JsonDocument& document);
  void ParseWsFillInfoList(const JsonDocument& document);
  void ParseOrderInfo(const JsonValue& data, coin::proto::ProductOrderElement* order);
  void ParseFillInfo(const JsonValue& data, coin::proto::ProductFillElement* fill);

  void ParseRestDeposit();
  void ParseRestWithdrawal();
  void ParseRestTransfer();

 private:
  bool is_account_balance_initialized_ = false;
  bool parse_in_progress_ = false;
  std::map<std::string, std::string> transfer_deposit_map_;
  bool is_transfer_deposit_initialized_ = false;
  std::map<std::string, std::string> transfer_withdrawal_map_;
  bool is_transfer_withdrawal_initialized_ = false;
  std::map<std::string, std::string> transfer_record_map_;
  bool is_transfer_deposit_subaccount_initialized_ = false;
  bool is_transfer_withdrawal_subaccount_initialized_ = false;

  bool is_transfer_initialized_ = false;
};
}  // namespace coin2::exchange::okex_v5::order_v5
